package org.wesc.boot.service.system.notice;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wesc.boot.common.constant.CommonConstant;
import org.wesc.boot.dao.domain.QueryRequest;
import org.wesc.boot.dao.entity.Notice;
import org.wesc.boot.dao.entity.UserMessage;
import org.wesc.boot.dao.mapper.NoticeMapper;
import org.wesc.boot.dao.mapper.UserMessageMapper;
import org.wesc.boot.dao.service.NoticeService;
import org.wesc.boot.dao.utils.SortUtil;
import org.wesc.boot.service.websocket.WebSocket;
import org.wesc.boot.service.websocket.WebSocketConstant;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * 系统通告高级服务
 *
 * @author Wesley
 * @date 2021/3/29
 */
@Slf4j
@Service
public class NoticeAdvanceService {

    private final NoticeMapper noticeMapper;

    private final NoticeService noticeService;

    private final UserMessageMapper userMessageMapper;

    @Resource
    private WebSocket webSocket;

    @Autowired
    public NoticeAdvanceService(NoticeMapper noticeMapper, NoticeService noticeService, UserMessageMapper userMessageMapper) {
        this.noticeMapper = noticeMapper;
        this.noticeService = noticeService;
        this.userMessageMapper = userMessageMapper;
    }

    /**
     * 分页查询通告
     */
    public IPage<Notice> pageQueryList(QueryRequest request, Notice notice) {
        try {
            LambdaQueryWrapper<Notice> queryWrapper = new LambdaQueryWrapper<>();
            // 过滤已删除通告
            queryWrapper.eq(Notice::getDelFlag, CommonConstant.DEL_FLAG_0);
            // 构建查询条件
            if (StringUtils.isNotBlank(notice.getTitle())) {
                queryWrapper.like(Notice::getTitle, notice.getTitle());
            }
            Page<Notice> page = new Page<>();
            SortUtil.handlePageSort(request, page, true);
            return noticeService.page(page, queryWrapper);
        } catch (Exception e) {
            log.error("获取消息失败", e);
            return null;
        }
    }

    /**
     * 创建通告
     */
    @Transactional(rollbackFor = Exception.class)
    public Notice create(Notice notice, String userName) {
        // 默认为通知公告
        notice.setMsgCategory("1");
        // 通告新增时为未删除状态
        notice.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
        // 通告新增时为未发布状态
        notice.setSendStatus(INoticeConstant.UNPUBLISHED_STATUS_0);
        // 通告创建者信息
        notice.setCreateBy(userName);
        notice.setCreateTime(LocalDateTime.now());

        if (notice.getMsgType().equals(INoticeConstant.MSG_TYPE_ALL)) {
            this.noticeMapper.insert(notice);
        } else {
            // 1.插入通告表
            this.noticeMapper.insert(notice);
            // 2.插入用户消息阅读标记表
            String userId = notice.getUserIds();
            String[] userIds = userId.substring(0, (userId.length() - 1)).split(",");
            String noticeId = notice.getId();
            for (String id : userIds) {
                UserMessage message = new UserMessage();
                message.setNoticeId(noticeId);
                message.setUserId(id);
                message.setReadFlag(INoticeConstant.NO_READ_FLAG);
                message.setCreateBy(userName);
                message.setCreateTime(LocalDateTime.now());
                this.userMessageMapper.insert(message);
            }
        }
        return notice;
    }

    /**
     * 编辑通告
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(Notice notice, String userName) {
        notice.setUpdateBy(userName);
        notice.setUpdateTime(LocalDateTime.now());
        this.noticeService.updateById(notice);

        String userId = notice.getUserIds();
        if (StringUtils.isNotEmpty(userId) && notice.getMsgType().equals(INoticeConstant.MSG_TYPE_USER)) {
            // 补充新的用户消息
            String[] userIds = userId.substring(0, (userId.length() - 1)).split(StringPool.COMMA);
            String noticeId = notice.getId();
            for (String id : userIds) {
                LambdaQueryWrapper<UserMessage> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(UserMessage::getNoticeId, noticeId);
                queryWrapper.eq(UserMessage::getUserId, id);
                List<UserMessage> userMessageList = this.userMessageMapper.selectList(queryWrapper);
                if (userMessageList.size() <= 0) {
                    // 增加指定用户：增量新增用户消息
                    UserMessage userMessage = new UserMessage();
                    userMessage.setNoticeId(noticeId);
                    userMessage.setUserId(id);
                    userMessage.setReadFlag(INoticeConstant.NO_READ_FLAG);
                    userMessage.setCreateBy(userName);
                    userMessage.setCreateTime(LocalDateTime.now());
                    this.userMessageMapper.insert(userMessage);
                }
            }
            // 删除指定用户：删除多余用户消息
            Collection<String> delUserIds = Arrays.asList(userIds);
            LambdaQueryWrapper<UserMessage> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.notIn(UserMessage::getUserId, delUserIds);
            queryWrapper.eq(UserMessage::getNoticeId, noticeId);
            this.userMessageMapper.delete(queryWrapper);
        }
    }

    /**
     * 删除通告: 设置删除标识
     */
    @Transactional(rollbackFor = Exception.class)
    public void batchDelete(String[] ids, String userName) {
        if (null == ids || ids.length == 0) {
            return;
        }
        for (String id : ids) {
            Notice notice = this.noticeService.getById(id);
            if (null != notice) {
                notice.setDelFlag(CommonConstant.DEL_FLAG_1.toString());
                notice.setUpdateBy(userName);
                notice.setUpdateTime(LocalDateTime.now());
                this.noticeService.updateById(notice);
            }
        }
    }


    /**
     * 发布通告
     */
    public Notice publish(String currentUserName, String id) {
        Notice notice = this.noticeService.getById(id);
        if (null == notice) {
            return null;
        }
        // 发布
        notice.setSendStatus(INoticeConstant.PUBLISHED_STATUS_1);
        notice.setSendTime(LocalDateTime.now());
        notice.setSender(currentUserName);
        this.noticeService.updateById(notice);
        if (notice.getMsgType().equals(INoticeConstant.MSG_TYPE_ALL)) {
            // 全体用户
            JSONObject obj = new JSONObject();
            obj.put(WebSocketConstant.MSG_CMD, WebSocketConstant.CMD_TOPIC);
            obj.put(WebSocketConstant.MSG_ID, notice.getId());
            obj.put(WebSocketConstant.MSG_TXT, notice.getTitle());
            webSocket.sendMessage(obj.toJSONString());
        } else {
            // 指定用户：插入用户通告阅读标记表记录
            String userId = notice.getUserIds();
            String[] userIds = userId.substring(0, (userId.length() - 1)).split(",");
            JSONObject obj = new JSONObject();
            obj.put(WebSocketConstant.MSG_CMD, WebSocketConstant.CMD_USER);
            obj.put(WebSocketConstant.MSG_ID, notice.getId());
            obj.put(WebSocketConstant.MSG_TXT, notice.getTitle());
            webSocket.sendMessage(userIds, obj.toJSONString());
        }
        return notice;
    }


    /**
     * 撤销通告
     */
    public Notice revoke(String id) {
        Notice notice = this.noticeService.getById(id);
        if (null == notice) {
            return null;
        } else {
            // 撤销发布
            notice.setSendStatus(INoticeConstant.REVOKE_STATUS_2);
            notice.setCancelTime(LocalDateTime.now());
            this.noticeService.updateById(notice);
            return notice;
        }
    }

    /**
     * 同步通告
     */
    public Notice sync(String userId, String noticeId) {
        JSONObject obj = new JSONObject();
        Notice notice = this.noticeService.getById(noticeId);
        if (null == notice) {
            return null;
        } else {
            if (notice.getMsgType().equals(INoticeConstant.MSG_TYPE_ALL)) {
                obj.put(WebSocketConstant.MSG_CMD, WebSocketConstant.CMD_TOPIC);
                obj.put(WebSocketConstant.MSG_ID, notice.getId());
                obj.put(WebSocketConstant.MSG_TXT, notice.getTitle());
                webSocket.sendMessage(obj.toJSONString());
            } else {
                obj.put(WebSocketConstant.MSG_CMD, WebSocketConstant.CMD_USER);
                obj.put(WebSocketConstant.MSG_ID, notice.getId());
                obj.put(WebSocketConstant.MSG_TXT, notice.getTitle());
                webSocket.sendMessage(userId, obj.toJSONString());
            }
        }
        return notice;
    }

    /**
     * 同步所有
     */
    public void syncAll(String userId) {
        JSONObject obj = new JSONObject();
        obj.put(WebSocketConstant.MSG_CMD, "");
        obj.put(WebSocketConstant.MSG_ID, "");
        obj.put(WebSocketConstant.MSG_TXT, "批量设置已读");
        webSocket.sendMessage(userId, obj.toJSONString());
    }

}
